//! 查询优化器测试模块
//!
//! 测试查询优化器的各个组件：
//! - 统计信息收集
//! - 成本估算模型
//! - 计划缓存
//! - 优化规则

use super::optimizer::*;
use crate::sql::Value;
use std::sync::Arc;

/// 查询优化器测试套件
pub struct OptimizerTestSuite {
    statistics_collector: Arc<StatisticsCollector>,
    cost_model: CostModel,
    plan_cache: PlanCache,
}

impl OptimizerTestSuite {
    /// 创建新的测试套件
    pub fn new() -> Self {
        let statistics_collector = Arc::new(StatisticsCollector::new());
        let cost_model = CostModel::new(statistics_collector.clone());
        let plan_cache = PlanCache::new();

        Self {
            statistics_collector,
            cost_model,
            plan_cache,
        }
    }
    
    /// 测试统计信息收集
    pub fn test_statistics_collection(&self) -> Result<(), crate::Error> {
        println!("🧪 测试统计信息收集...");
        
        // 创建测试数据
        let test_data = vec![
            vec![Value::Integer(1), Value::Text("Alice".to_string()), Value::Integer(25)],
            vec![Value::Integer(2), Value::Text("Bob".to_string()), Value::Integer(30)],
            vec![Value::Integer(3), Value::Text("Charlie".to_string()), Value::Integer(35)],
            vec![Value::Integer(4), Value::Text("Diana".to_string()), Value::Integer(28)],
            vec![Value::Integer(5), Value::Null, Value::Integer(32)],
        ];
        
        // 收集表统计信息
        self.statistics_collector.collect_table_statistics("users", &test_data)?;
        
        // 验证表统计信息
        let table_stats = self.statistics_collector.get_table_statistics("users")
            .expect("应该有表统计信息");
        
        assert_eq!(table_stats.row_count, 5);
        assert!(table_stats.avg_row_size > 0.0);
        assert!(table_stats.page_count > 0);
        
        // 收集列统计信息
        self.statistics_collector.collect_column_statistics("users", "id", 0, &test_data)?;
        self.statistics_collector.collect_column_statistics("users", "name", 1, &test_data)?;
        self.statistics_collector.collect_column_statistics("users", "age", 2, &test_data)?;
        
        // 验证列统计信息
        let id_stats = self.statistics_collector.get_column_statistics("users", "id")
            .expect("应该有ID列统计信息");
        assert_eq!(id_stats.distinct_count, 5);
        assert_eq!(id_stats.null_count, 0);
        
        let name_stats = self.statistics_collector.get_column_statistics("users", "name")
            .expect("应该有name列统计信息");
        assert_eq!(name_stats.distinct_count, 4); // 一个NULL值
        assert_eq!(name_stats.null_count, 1);
        
        let age_stats = self.statistics_collector.get_column_statistics("users", "age")
            .expect("应该有age列统计信息");
        assert_eq!(age_stats.distinct_count, 5);
        assert_eq!(age_stats.null_count, 0);
        
        println!("✅ 统计信息收集测试通过");
        Ok(())
    }
    
    /// 测试成本模型参数
    pub fn test_cost_model_parameters(&self) -> Result<(), crate::Error> {
        println!("🧪 测试成本模型参数...");

        // 先收集统计信息
        let test_data = vec![
            vec![Value::Integer(1), Value::Text("Alice".to_string())],
            vec![Value::Integer(2), Value::Text("Bob".to_string())],
            vec![Value::Integer(3), Value::Text("Charlie".to_string())],
        ];
        self.statistics_collector.collect_table_statistics("test_table", &test_data)?;

        // 测试成本参数
        let params = self.cost_model.get_parameters();
        assert!(params.seq_scan_cost_per_row > 0.0);
        assert!(params.index_scan_cost_per_row > 0.0);
        assert!(params.cpu_cost_per_row > 0.0);

        println!("  顺序扫描成本: {:.4}", params.seq_scan_cost_per_row);
        println!("  索引扫描成本: {:.4}", params.index_scan_cost_per_row);
        println!("  CPU处理成本: {:.4}", params.cpu_cost_per_row);

        println!("✅ 成本模型参数测试通过");
        Ok(())
    }
    
    /// 测试计划缓存基础功能
    pub fn test_plan_cache_basic(&self) -> Result<(), crate::Error> {
        println!("🧪 测试计划缓存基础功能...");

        let query_hash = "test_query_hash".to_string();

        // 测试缓存未命中
        assert!(self.plan_cache.get(&query_hash).is_none());

        // 测试缓存统计信息
        let stats = self.plan_cache.get_stats();
        assert_eq!(stats.misses, 1);

        // 测试缓存配置
        let hit_rate = self.plan_cache.hit_rate();
        assert_eq!(hit_rate, 0.0); // 没有命中

        println!("  初始命中率: {:.2}%", hit_rate * 100.0);

        println!("✅ 计划缓存基础功能测试通过");
        Ok(())
    }
    
    /// 测试统计信息配置
    pub fn test_statistics_config(&self) -> Result<(), crate::Error> {
        println!("🧪 测试统计信息配置...");

        // 测试默认配置
        let config = StatisticsConfig::default();
        assert_eq!(config.max_age_seconds, 3600);
        assert_eq!(config.histogram_buckets, 100);
        assert_eq!(config.auto_update_threshold, 0.1);
        assert_eq!(config.sampling_rate, 0.1);

        // 测试自定义配置
        let custom_config = StatisticsConfig {
            max_age_seconds: 7200,
            histogram_buckets: 200,
            auto_update_threshold: 0.2,
            sampling_rate: 0.05,
        };

        assert_eq!(custom_config.max_age_seconds, 7200);
        assert_eq!(custom_config.histogram_buckets, 200);

        println!("  默认过期时间: {}秒", config.max_age_seconds);
        println!("  默认直方图桶数: {}", config.histogram_buckets);

        println!("✅ 统计信息配置测试通过");
        Ok(())
    }
    
    /// 测试成本参数更新
    pub fn test_cost_parameters_update(&mut self) -> Result<(), crate::Error> {
        println!("🧪 测试成本参数更新...");

        // 获取原始参数
        let original_params = self.cost_model.get_parameters().clone();

        // 创建新参数
        let new_params = CostParameters {
            seq_scan_cost_per_row: 2.0,
            index_scan_cost_per_row: 0.2,
            random_page_cost: 8.0,
            sequential_page_cost: 2.0,
            cpu_cost_per_row: 0.02,
            memory_cost_per_byte: 0.000002,
            join_base_cost: 20.0,
            sort_base_cost: 10.0,
        };

        // 更新参数
        self.cost_model.update_parameters(new_params.clone());

        // 验证参数已更新
        let updated_params = self.cost_model.get_parameters();
        assert_eq!(updated_params.seq_scan_cost_per_row, 2.0);
        assert_eq!(updated_params.join_base_cost, 20.0);

        println!("  原始顺序扫描成本: {:.4}", original_params.seq_scan_cost_per_row);
        println!("  更新后顺序扫描成本: {:.4}", updated_params.seq_scan_cost_per_row);

        println!("✅ 成本参数更新测试通过");
        Ok(())
    }
    
    /// 运行完整的优化器测试套件
    pub fn run_full_test_suite(&mut self) -> Result<(), crate::Error> {
        println!("🚀 开始查询优化器测试套件...");
        println!("=====================================");

        self.test_statistics_collection()?;
        self.test_cost_model_parameters()?;
        self.test_plan_cache_basic()?;
        self.test_statistics_config()?;
        self.test_cost_parameters_update()?;

        println!("=====================================");
        println!("🎉 查询优化器测试套件全部通过！");

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_statistics_collection() {
        let test_suite = OptimizerTestSuite::new();
        test_suite.test_statistics_collection().unwrap();
    }

    #[test]
    fn test_cost_model_parameters() {
        let test_suite = OptimizerTestSuite::new();
        test_suite.test_cost_model_parameters().unwrap();
    }

    #[test]
    fn test_plan_cache_basic() {
        let test_suite = OptimizerTestSuite::new();
        test_suite.test_plan_cache_basic().unwrap();
    }

    #[test]
    fn test_statistics_config() {
        let test_suite = OptimizerTestSuite::new();
        test_suite.test_statistics_config().unwrap();
    }

    #[test]
    fn test_cost_parameters_update() {
        let mut test_suite = OptimizerTestSuite::new();
        test_suite.test_cost_parameters_update().unwrap();
    }

    #[test]
    fn test_full_optimizer_suite() {
        let mut test_suite = OptimizerTestSuite::new();
        test_suite.run_full_test_suite().unwrap();
    }
}
